(function() {
    if (!window['BINGO']) {
        window['BINGO'] = {};
    }


    function map() {
        this.data = [];
    };
    map.prototype.clear = function() {
        this.data = [];
    };
    map.prototype.get = function(k) {
        var v = null;
        $(this.data).each(function(i) {
            if (objectEqual(this.key, k)) {
                v = this.value;
                return false;
            }
        });
        return v;
    };
    map.prototype.put = function(k, v) {
        var has = false;
        $(this.data).each(function(i) {
            if (objectEqual(this.key, k)) {
                this.value = v;
                has = true;
                return false;
            }
        });
        if (!has) {
            this.data.push({
                key: k,
                value: v
            });
        }
    };
    map.prototype.remove = function(k) {
        var t = jQuery.grep(this.data, function(d, i) {
            if (!objectEqual(d.key, k)) {
                return d;
            }
        });
        this.data = t;
    };
    map.prototype.isEmpty = function() {
        if (this.data.length == 0) {
            return true;
        }
        else {
            return false;
        }
    };
    map.prototype.size = function() {
        return this.data.length;
    };
    map.prototype.containsKey = function(k) {
        $(this.data).each(function(i) {
            if (objectEqual(this.key, k)) {
                return true;
            }
        });
        return false;
    };
    map.prototype.getValues = function() {
        var result = [];
        $(this.data).each(function(i) {
            result.push(this.value);
        });
        return result;
    };
    map.prototype.getKeys = function() {
        var result = [];
        $(this.data).each(function(i) {
            result.push(this.key);
        });
        return result;
    };

    window['BINGO']['map'] = map;

    function objectEqual(obj1, obj2) {
        if (jQuery.isPlainObject(obj1)) {
            for (var i in obj1) {
                if (obj1[i] != obj2[i]) {
                    return false;
                }
            }
            return true;
        }
        else {
            return obj1 === obj2;
        }
    };

    valueLimit = function(len, min, max) {
        min = min || 0;
        max = max || Number.MAX_VALUE;

        return min <= len && len <= max;
    };


    LenB = function(str) {
        return str.replace(/[^\x00-\xff]/g, "**").length;
    };


    function ajaxValidate(form) {
        var rn = true;
        var validate = $(form).data('validate');
        if (validate) {
            $(validate).each(function(){
                if(BINGO.Validator.validate(this, false)){
                    rn = false;
                }
            });

        }

        return rn;
    };
    window['BINGO']['ajaxValidate'] = ajaxValidate;





    var Validator = {
        require: /.+/,
        email: /(^[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-])+(\.[A-Za-z0-9-]+)*((\.com)|(\.net)|(\.org)|(\.info)|(\.edu)|(\.mil)|(\.gov)|(\.biz)|(\.ws)|(\.us)|(\.tv)|(\.cc)|(\.aero)|(\.arpa)|(\.coop)|(\.int)|(\.jobs)|(\.museum)|(\.name)|(\.pro)|(\.travel)|(\.nato)|(\.[A-Za-z0-9]{2,3})|(\.[A-Za-z0-9]{2,3}\.[A-Za-z0-9]{2,3}))$)/,
        url: /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,
        number: /^\d+$/,
        posNumber:/^[0-9]*[1-9][0-9]*$/,
        integer: /^[-\+]?\d+$/,
        double: /^[-\+]?\d+(\.\d+)?$/,
        english: /^[A-Za-z]+$/,
        chinese: /^[\u0391-\uFFE5]+$/,
        ipAddress: /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/,
        MAC: /^([0-9A-Fa-f]{2})(-[0-9A-Fa-f]{2}){5}$/,
        domain: /^[A-Za-z0-9\_\.]+$/,
        englishNumber: /^[0-9A-Za-z]+$/,
        chineseEnglishNumber:/^[\u4E00-\u9FA5\uf900-\ufa2dA-Za-z0-9_]+$/,      //中文、英文、数字、下划线
        mobile: /^(1)[0-9]{10}$/,				//手机
        telNum: /^((180|181|189|133|153|177)\\d{8})|(1700\\d{7})$/,       //电信号码
        currency: /^\d+(\.\d{0,2})?$/,
        date: /^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))$/,
        time: /^(20|21|22|23|[0-1][0-9]):[0-5][0-9]:[0-5][0-9]$/,
        dateTime: /^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)) (20|21|22|23|[0-1][0-9]):[0-5][0-9]:[0-5][0-9]$/,
        dateTime_noSec: /^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)) (20|21|22|23|[0-1][0-9]):[0-5][0-9]$/,
        englishNumberCode: /^[_A-Za-z0-9-\(\)\[\]]*$/,

        defaultMsg:{
        	require:"不能为空",
        	number:"必须是数字类型",
        	englishNumber:"只支持英文和数字"
        	
        },
        test: function(dataType, value, min, max) {
            //var value = trim(value);

            switch (dataType) {
                case "Require":
                    return !Validator[dataType].test(value);
                    break;
                case "email":
                case "url":
                case "number":
                case "integer":
                case "double":
                case "ipAddress":
                case "english":
                case "posNumber":
                case "MAC":
                case "domain":
                case "englishNumber":
                case "englishNumberCode":
                case "chineseEnglishNumber":
                case "mobile":
                case "telNum":
                case "currency":
                case "date":
                case "dateTime":
                case "dateTime_noSec":
                    if(value != "")
                        return !Validator[dataType].test(value);
                    break;
                case "range":
                    return value.length == 0 || min > value || max < value;
                    break;
                case "lenLimit":
                    return !valueLimit(value.length, min, max);
                    break;
                case "lenLimitB":
                    return !valueLimit(LenB(value), min, max);
                    break;
            }
            return null;
        },
        compare : function(v1, operator, v2, msg) {
            switch (operator) {
                case "notEqual":
                    if (v1 == v2) {
                        return msg;
                    }
                    break;
                case "greaterThan":
                    if (isNaN(v1) || isNaN(v2)) {
                        if (v1 <= v2) {
                            return msg;
                        }
                    }
                    else if (Number(v1) <= Number(v2)) {
                        return msg;
                    }
                    break;
                case "greaterThanEqual":
                    if (isNaN(v1) || isNaN(v2)) {
                        if (v1 < v2) {
                            return msg;
                        }
                    }
                    else if (Number(v1) < Number(v2)) {
                        return msg;
                    }
                    break;
                case "lessThan":
                    if (isNaN(v1) || isNaN(v2)) {
                        if (v1 >= v2) {
                            return msg;
                        }
                    }
                    else if (Number(v1) >= Number(v2)) {
                        return msg;
                    }
                    break;
                case "lessThanEqual":
                    if (isNaN(v1) || isNaN(v2)) {
                        if (v1 > v2) {
                            return msg;
                        }
                    }
                    else if (Number(v1) > Number(v2)) {
                        return msg;
                    }
                    break;
                default:
                    if (v1 != v2) {
                        return msg;
                    }
                    break;
            }
            return null;
        },

        renderInput : function(ts, success, msg) {
            var info = $(ts).parent().find('.column-info');
            info.removeClass('error');
            if(msg != null){
                if (success) {
                    //info.addClass('column-hint');
                }else{
                    info.addClass('error');
                }
                info.text(msg);

                info.show();
                info.css('display','inline-block');
                return true;
            }else{
                info.text('');
                info.hide();
                return false;
            }

        },
        validate : function(ts, success){
            //var value = getElmtValWithEasyui($(ts));
            if ($(ts).attr('hint') == 'true') {
                $(ts).val('');
            }
            //value = trim(value);
            //$(ts).val(value);

            var msg = null;
            $($(ts).data('validate').getKeys()).each(function() {
                var fun = $(ts).data('validate').get(this);
                if(success){
                    msg = this.msg;
                }
                if (fun()) {
                    if(!success){
                        msg = this.msg;
                    }
                    return false;
                }
            });
            return this.renderInput(ts, success, msg);
        }
    };
    window['BINGO']['Validator'] = Validator;

})();


(function($) {

    $.fn.validateRegister = function(dataType, msg, min, max) {
    	var Validator = window['BINGO']['Validator'] ;;
    	if(msg==null||msg==''){
    		msg = Validator.defaultMsg[dataType+""];
    		if(msg==null)msg="默认校验信息不存在($.fn.validateRegister )！";
    	}
    	var form = $(this).closest('form');
        
        var error = null;
        var ts = $(this);

        if (!form.data('validate')) {
            form.data('validate', []);
        }

        if (!ts.data('validate')) {
            ts.data('validate', new BINGO.map());
            form.data('validate').push(this);

            $(this).bind("focusin", function(){
                BINGO.Validator.validate(this, true);
            });
            $(this).bind("focusout", function(){
                BINGO.Validator.validate(this, false);
            });
            $(this).bind("keyup", function(){
                BINGO.Validator.validate(this, true);
            });
        }
        ts.data('validate').put({dataType: dataType, msg: msg}, function() {
            return BINGO.Validator.test(dataType, ts.val(), min, max);
        });


    };

    $.fn.compareRegister = function(operator, id2, msg, rendererID) {
        var form = $(this).closest('form');

        var error = null;
        var ts = $(this);

        if (!form.data('validate')) {
            form.data('validate', []);
        }

        if (!ts.data('validate')) {
            ts.data('validate', new BINGO.map());
            form.data('validate').push(this);

            $(this).bind("focusin", function(){
                BINGO.Validator.validate(this, true);
            });
            $(this).bind("focusout", function(){
                BINGO.Validator.validate(this, false);
            });
            $(this).bind("keyup", function(){
                BINGO.Validator.validate(this, true);
            });


        }

        ts.data('validate').put({operator: operator, msg: msg}, function() {
            return BINGO.Validator.compare(ts.val(), operator, $('#' + id2).val(), msg);
        });

    };


    $.fn.clearValidateRegister = function() {
        var form = $(this).closest('form');
        var $_this = $(this);
        var ary_formData = form.data('validate');

        if (ary_formData) {
            //console.log(ary_formData);
            var n = 0;

            for (; n < ary_formData.length; n++) {
                if (ary_formData[n].attr("id") == this.attr("id")) {
                    //console.log(ary_formData[n].attr("id"));
                    //console.log(this.attr("id"));
                    break;
                }
            }

            //console.log('n = ' + n);
            ary_formData.splice(n, 1);
            //console.log(ary_formData);
        }

        $(this).unbind("focusin");
        $(this).unbind("focusout");
        $(this).unbind("keyup");

        if ($_this.data('validate')) {
            $_this.data('validate', null);
        }
    };


})(jQuery);